package cn.sylinx.horm.resource.parse;

import cn.sylinx.horm.config.ParseSqlType;
import cn.sylinx.horm.dialect.DbType;
import cn.sylinx.horm.resource.ClasspathSqlResource;
import cn.sylinx.horm.util.GLog;
import cn.sylinx.horm.util.Pair;

import java.util.Map;

public class DefaultSqlParser extends SqlParser {

    static final String SQL_POSTFIX = ".sql";

    private DbType dbtype;
    private String sqlPostfix;

    private final SqlParser sqlParserForSystem;
    private final SqlParser sqlParserForLiquor;
    private final SqlParser sqlParserForJava;

    public DefaultSqlParser() {
        this(null);
    }

    public DefaultSqlParser(DbType dbtype) {
        this(SQL_POSTFIX, dbtype);
    }

    public DefaultSqlParser(String sqlPostfix, DbType dbtype) {
        this.sqlPostfix = SQL_POSTFIX;
        this.dbtype = dbtype;
        // system
        sqlParserForSystem = new SystemSqlParser(sqlPostfix, dbtype);
        // liquor
        sqlParserForLiquor = new LiquorSqlParser(sqlPostfix, dbtype);
        // java
        sqlParserForJava = new JavaSqlParser(sqlPostfix, dbtype);
    }


    public DbType getDbtype() {
        return dbtype;
    }

    public void setDbtype(DbType dbtype) {
        this.dbtype = dbtype;
        sqlParserForSystem.setDbtype(dbtype);
        sqlParserForLiquor.setDbtype(dbtype);
        // sqlParserForJava.setDbtype(dbtype);
    }

    public String getSqlPostfix() {
        return sqlPostfix;
    }

    public void setSqlPostfix(String sqlPostfix) {
        this.sqlPostfix = sqlPostfix;
        sqlParserForSystem.setSqlPostfix(sqlPostfix);
        sqlParserForLiquor.setSqlPostfix(sqlPostfix);
        // sqlParserForJava.setSqlPostfix(sqlPostfix);
    }

    public Pair parseSql(ClasspathSqlResource sqlResource, Map<String, Object> params) {

        Pair p = null;
        String type = sqlResource.getType();
        if (ParseSqlType.LIQUOR.getType().equals(type)) {
            p = sqlParserForLiquor.parseSql(sqlResource, params);
        } else if (ParseSqlType.SYSTEM.getType().equals(type)) {
            p = sqlParserForSystem.parseSql(sqlResource, params);
        } else if (ParseSqlType.JAVA.getType().equals(type)) {
            p = sqlParserForJava.parseSql(sqlResource, params);
        }
        GLog.debug("parseSql -> {}", p);

        return p;
    }

    public Pair parseSql(String statement, String type, Map<String, Object> params) {

        if (ParseSqlType.LIQUOR.getType().equals(type)) {
            return sqlParserForLiquor.parseSql(statement, type, params);
        }

        if (ParseSqlType.SYSTEM.getType().equals(type)) {
            return sqlParserForSystem.parseSql(statement, type, params);
        }

        if (ParseSqlType.JAVA.getType().equals(type)) {
            return sqlParserForJava.parseSql(statement, type, params);
        }

        return null;
    }

    @Override
    public String parseSqlPart(ClasspathSqlResource sqlResource, Map<String, Object> params) {

        String type = sqlResource.getType();
        if (ParseSqlType.LIQUOR.getType().equals(type)) {
            return sqlParserForLiquor.parseSqlPart(sqlResource, params);
        } else if (ParseSqlType.SYSTEM.getType().equals(type)) {
            return sqlParserForSystem.parseSqlPart(sqlResource, params);
        } else if (ParseSqlType.JAVA.getType().equals(type)) {
            return sqlParserForJava.parseSqlPart(sqlResource, params);
        }

        return null;
    }

    @Override
    public String parseSqlPart(String statement, String type, Map<String, Object> params) {

        if (ParseSqlType.LIQUOR.getType().equals(type)) {
            return sqlParserForLiquor.parseSqlPart(statement, type, params);
        }

        if (ParseSqlType.SYSTEM.getType().equals(type)) {
            return sqlParserForSystem.parseSqlPart(statement, type, params);
        }

        if (ParseSqlType.JAVA.getType().equals(type)) {
            return sqlParserForJava.parseSqlPart(statement, type, params);
        }

        return null;
    }

}